package com.ling.module1sbbyyds.config.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.ling.sbbyyds.entity.users.User;
import com.ling.module1sbbyyds.utils.UserThreadLocal;
import com.ling.sbbyyds.common.ToolKits;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * 天道酬勤、学无止境
 *
 * @Description: 登录拦截
 * @author: ling
 * @date: 2022年03月25日
 */
@Slf4j
@Component
public class UserInterceptor implements HandlerInterceptor {

    @Autowired
    private RedisTemplate<String, String> redis;

    /**
     * @param request  请求头
     * @param response 响应头
     * @param handler  头信息
     * @return 是否放行
     * @throws Exception 异常
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        User user = null;
        try {
            //判断用户有没有登录
            //获取请求中header的token
            String token = request.getHeader("AuthorizationOauth_Token");
            //获取到有token
            if (token != null) {
                //获取redis中是否有这个token   key:token  value: User(用户信息)
                String jsonUser = redis.opsForValue().get(token);
                //存在token，已登录
                if (jsonUser != null) {
                    user = JSONObject.parseObject(jsonUser, User.class);
                    //存用户信息
                    HashMap<String, Object> data = new HashMap<>();
                    data.put("user", user);
                    data.put("token", token);
                    data.put("ip", ToolKits.getRequestIp(request));
                    UserThreadLocal.put(data);
                    printLogger(request, user, "已登录");
                    return true;
                }
            }
        } catch (Exception e) {
            log.error("登录拦截器出现内部错误！");
            log.error("错误为：{}", e.toString());
        }
        printLogger(request, user, "未登录");
        //未登录，进行转发
        request.getRequestDispatcher("/api/err/noLogin").forward(request, response);
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // 清除线程中用户信息
        UserThreadLocal.remove();
    }

    private static Map<String, String> getHeaders(HttpServletRequest request) {
        Map<String, String> headerMap = new HashMap<>();
        Enumeration<String> enumeration = request.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String name = enumeration.nextElement();
            String value = request.getHeader(name);
            headerMap.put(name, value);
        }
        return headerMap;
    }

    /**
     * 请求打印
     *
     * @param request 请求头
     * @param user    用户信息
     * @param isLogin 是否登录
     */
    public void printLogger(HttpServletRequest request, User user, String isLogin) {
        Logger logger = LoggerFactory.getLogger("User");
        logger.info("------------------------[{}]---------------------", isLogin);
        logger.info("发起请求客户端:[{}]", request.getRemoteAddr());
        logger.info("请求方式:[{}]", request.getMethod());
        logger.info("请求路径:[{}]", request.getRequestURI());
        logger.info("请求参数:[{}]", request.getQueryString());
        if (user != null) {
            logger.info("用户名:[{}]", user.getUserName());
            logger.info("联系方式:[{}]", user.getPhone());
        }
        logger.info("----------------------------------------------------\n\n\n");
    }


}
